package com.dfl.launcher;

import android.os.RemoteException;
import android.util.Log;

import com.dfl.api.app.guistore.ISkinServiceCallback;
import com.dfl.api.app.guistore.SkinInfo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @noinspection RedundantThrows
 */
public class ClientImpl extends ISkinServiceCallback.Stub {

    @Override
    public boolean onHandleSkin(SkinInfo skinInfo) throws RemoteException {
        // 无需处理, 返回true即可.
        return true;
    }

    @Override
    public boolean onSkinPathChanged(SkinInfo skinInfo) throws RemoteException {
        Log.d("ChangeSkin[client]", "onSkinPathChanged");
        // 开始阻塞等待主线程换肤结束
        return handleSkinBlock(skinInfo);
    }

    @Override
    public boolean onDefaultSkin() throws RemoteException {
        // 与onSkinPathChanged一致
        return true;
    }

    /**
     * 阻塞等待主线程换肤结束.
     *
     * @param skinInfo 皮肤信息.
     * @return 换肤结果, [true: 换肤成功] [false: 换肤失败]
     */
    private boolean handleSkinBlock(SkinInfo skinInfo) {
        final long threadId = Thread.currentThread().getId();
        Log.d("ChangeSkin[client]", "handleSkinBlock, threadId: " + threadId);

        // 准备计数器
        final CountDownLatch listener = new CountDownLatch(1);

        // 通知换肤管理器执行换肤(模拟成功场景)
        Log.d("ChangeSkin[client]", "changeSkinSuccessCase");
        final AtomicReference<ChangeResult> ref = new AtomicReference<>(null);
        MockSkinManager.getInstance().changeSkinSuccessCase(
                skinInfo,
                changeResult -> {
                    // 设置换肤结果
                    ref.lazySet(changeResult);
                    // 更新计数
                    listener.countDown();
                }
        );

        // 通知换肤管理器执行换肤(模拟失败场景)
        // Log.d("ChangeSkin[client]", "changeSkinFailureCase");
        // MockSkinManager.getInstance().changeSkinFailureCase(
        //         skinInfo,
        //         changeResult -> {
        //             // 设置换肤结果
        //             ref.lazySet(changeResult);
        //             // 更新计数
        //             listener.countDown();
        //         }
        // );

        // 阻塞等待计数归零,换肤结束
        try {listener.await();} catch (InterruptedException e) {}

        // 计数归零, 处理换肤结果
        final ChangeResult result = ref.get();
        Log.d("ChangeSkin[client]", "loop quit, result: " + result);
        if (result instanceof ChangeResult.Success) {
            // 换肤成功
            final ChangeResult.Success success = (ChangeResult.Success) result;
            final SkinInfo skin = success.getSkinInfo();
            Log.d("ChangeSkin[client]", "change skin success, skinId: " + skin.getSkinId());
            return true;
        } else {
            // 换肤失败
            final ChangeResult.Failure failure = (ChangeResult.Failure) result;
            Log.e("ChangeSkin[client]", "change skin failure", failure.getE());
            return false;
        }
    }

}
